<template>
  <div
    class="custom-table-wrapper"
    v-loading="config.loading"
    element-loading-text="数据加载中"
    element-loading-spinner="el-icon-loading"
    element-loading-background="rgba(255, 255, 255, 0.7)"
    :style="{
      boxShadow: config.isBoxShadow ? '0 3px 6px rgb(0 0 0 / 3%)' : '',
    }"
  >
    <!-- 表格内容 -->
    <el-table
      ref="customTableRef"
      :header-cell-style="
        config?.headerCellStyle ?? {
          backgroundColor: '#F6F6F6',
          'text-align': 'left',
          color: '#666666',
        }
      "
      :data="tableList"
      :height="config.height"
      :max-height="config.maxHeight"
      :stripe="config.stripe ?? true"
      :border="config.border ?? true"
      :size="config.size || 'small'"
      :fit="config.fit ?? true"
      :show-header="config.showHeader"
      :highlight-current-row="config.highlight === undefined ? true : config.highlight"
      :current-row-key="config.rowKey"
      :row-key="config.rowKey"
      :empty-text="config.emptyText ?? '暂无数据'"
      :show-summary="config.summary"
      :sum-text="config.summaryText ?? '合计'"
      @selection-change="selectionChange"
      @sort-change="config.sortChange ?? function () {}"
      @filter-change="config.filterChange ?? function () {}"
      :row-style="rowStyle"
      @row-dblclick="dbClickHandler"
      @cell-click="cellClickHandler"
    >
      <!-- 判断是否开启选择功能 -->
      <template v-if="config.selectable">
        <!-- 多选 -->
        <el-table-column
          v-if="config.multiple"
          width="55"
          type="selection"
          :reserve-selection="true"
          :selectable="config.selectHandler"
        >
        </el-table-column>
        <!-- 单选 -->
        <el-table-column v-else align="center" width="55">
          <template #default="scope">
            <el-radio
              v-model="radioSelected"
              :label="scope.row[config.rowKey || 'id']"
              @click.native.prevent="radioClick(scope.row[config.rowKey || 'id'], scope.row)"
              >{{ '' }}</el-radio
            >
          </template>
        </el-table-column>
      </template>
      <!-- 判断是否有序列号 -->
      <el-table-column
        v-if="config.indexable ?? true"
        type="index"
        width="55"
        align="center"
        :index="config.indexMethod"
        :label="config.indexLabel"
      ></el-table-column>

      <template v-for="(item, index) of column">
        <el-table-column
          v-if="checkedField.includes(item.field)"
          :key="index"
          :prop="item.field"
          :label="item.title ? item.title : item.field"
          :width="item.width"
          :fixed="item.fixed"
          :align="item.align"
          :formatter="item.formatter"
          :header-align="item.align || 'left'"
          :render-header="item.renderHeader"
          :show-overflow-tooltip="item.tooltip ?? true"
          :sortable="item.sortable"
        >
          <!-- 如果是组件的时候 -->
          <template v-if="item.type === 'component'">
            <KeepAlive>
              <component :is="item.component" :rowData="scope.row"></component>
            </KeepAlive>
          </template>
          <!-- 如果是使用插槽的时候 -->
          <template v-if="item.type === 'slot'" #default="scope">
            <slot
              :name="item.slotName ?? item.field"
              :field="item"
              :row="scope.row"
              :column="scope.column"
              :index="scope.$index"
            ></slot>
          </template>
        </el-table-column>
      </template>
    </el-table>
    <!-- 分页处理 -->
    <IElPager :tablePage="config.pagination" @onChange="changePageHandler"></IElPager>
  </div>
</template>

<script>
import IElPager from './../IElPager';
export default {
  name: 'IElTable',
  props: {
    config: {
      type: Object,
      required: true,
      default: () => {},
    },
    //table数据
    tableList: {
      type: Array,
      default: () => [],
      required: true,
    },
    // 表格的列
    column: {
      type: Array,
      default: () => [],
      required: true,
    },
  },
  data() {
    return {
      selectionList: [],
      radioSelected: null,
      isFirstPage: true,
      isLastPage: true,
      currentPage: {
        pageSize: this.config.pagination.pageSize ?? 10,
        pageNumber: this.config.pagination.currentPage ?? 1,
      },
      // 选中的列
      checkedField: [],
      headerRowStyle: {
        backgroundColor: '#f00',
      },
      dataRow: this.tableList[0], // 当前已选择行
      currentIndex: 0, // 当前选择行的index
    };
  },
  computed: {
    isMultiple() {
      return this.config.multiple;
    },
  },
  mounted() {
    this.$nextTick(() => {
      addEventListener('keyup', this.keyUp); //创建监听键盘事件
    });
  },
  methods: {
    cellClickHandler(row, column, cell, event) {
      console.log(row, column, cell, event, '11');
    },
    // 单选
    radioClick(rowKey, rowData) {
      console.log(rowKey, rowData, '1111');
      if (this.radioSelected == rowKey) {
        this.radioSelected = null;
        this.selectionList = [];
      } else {
        this.radioSelected = rowKey;
        this.selectionList = [rowData];
      }
      this.config.selectionChange && this.config.selectionChange(this.selectionList);
    },
    // 多选
    selectionChange(selection) {
      console.log(selection, '多选');
      this.selectionList = selection;
      console.log(this.selectionList, '1111');
      this.config.selectionChange && this.config.selectionChange(this.selectionList);
    },
    // 点击分页
    changePageHandler(pageNumber, pageSize) {
      this.config.pagination.onChange && this.config.pagination.onChange(pageNumber, pageSize);
    },
    // 赋值给多选方法
    multipleDefaultValue(newVal) {
      // 1.先清空已经选择的数据
      console.log(this.$refs, this.$refs.customTableRef, '111hah ');
      this.$refs.customTableRef.clearSelection();
      // 2.循环表格数据,如果当前项在defaultValue数组中就选中
      for (const item of this.tableList) {
        if (newVal.includes(item[this.config.rowKey || 'id'])) {
          this.$refs.customTableRef.toggleRowSelection(item, true);
        }
      }
    },
    handleCheckedFieldChange(field) {
      this.checkedField = field;
    },
    // 键盘移动的时候单选框的时候选中
    moveSelectRowHandler(rowData) {
      if (!this.isMultiple) {
        this.radioClick(rowData[this.config.rowKey || 'id'], rowData);
      }
    },
    // 左右键选中和取消复选框 <添加 > 删除
    checkOrCancelRowHandler(rowData, type = 'left') {
      console.log(rowData, type, '左右键盘操作');
      if (type == 'left') {
        const rowKeyList = [...this.selectionList, rowData].map((item) => item[this.config.rowKey || 'id']);
        this.multipleDefaultValue(rowKeyList);
      } else if (type == 'right') {
        console.log(this.selectionList, '历史选中');
        const rowKeyList = this.selectionList
          .filter((item) => item[this.config.rowKey || 'id'] != rowData[this.config.rowKey || 'id'])
          .map((item) => item[this.config.rowKey || 'id']);
        console.log(rowKeyList, '最后的');
        this.multipleDefaultValue(rowKeyList);
      } else {
        console.error('当前参数错误');
      }
    },
    // 键盘事件
    keyUp(e) {
      console.log(e.keyCode, '当前键盘');
      // 表格为空，不执行下方
      if (this.tableList.length == 0) {
        return;
      }
      if (e.keyCode == 40) {
        // 下键
        if (this.currentIndex == this.tableList.length - 1) {
          this.currentIndex = 0; //当选中的index与数据的天数相等时，在按下键就要返回第一个
          this.dataRow = this.tableList[0];
          let height = 36; //计算表格一行的高度，用于出现滚动条的时候，页面展示选中的某一行
          console.log(this.$refs.customTableRef);
          if (this.$refs.customTableRef) {
            this.$refs.customTableRef.bodyWrapper.scrollTop = -(height * (this.tableList.length - 6));
          }

          this.moveSelectRowHandler(this.dataRow);
        } else {
          if (this.currentIndex > 6 && this.currentIndex < 14) {
            let height = 36; //计算选中行离表格顶部的距离
            if (this.$refs.customTableRef) {
              this.$refs.customTableRef.bodyWrapper.scrollTop = height * (this.currentIndex - 6);
            }
          }
          this.currentIndex = this.currentIndex + 1;
          this.dataRow = this.tableList[this.currentIndex]; // 当前已选择行
          this.moveSelectRowHandler(this.dataRow);
        }
      } else if (e.keyCode == 38) {
        // 上键
        if (this.currentIndex == 0) {
          //当选中的index等于0时，说明到顶了，再按上键就要返回到表格的底部，并计算距离表格顶部的距离
          this.currentIndex = this.tableList.length - 1;
          this.dataRow = this.tableList[this.currentIndex]; // 当前已选择行
          let height = 36;
          if (this.$refs.customTableRef) {
            this.$refs.customTableRef.bodyWrapper.scrollTop = height * (this.tableList.length - 6);
          }

          this.moveSelectRowHandler(this.dataRow);
        } else {
          this.currentIndex = this.currentIndex - 1;
          this.dataRow = this.tableList[this.currentIndex];
          let height = 36;
          console.log(this.$refs.customTableRef, '1111111111111111');
          if (this.$refs.customTableRef) {
            this.$refs.customTableRef.bodyWrapper.scrollTop += -(height * 1);
          }

          this.moveSelectRowHandler(this.dataRow);
        }
      } else if (e.keyCode == 37) {
        console.log('左键选中');
        this.checkOrCancelRowHandler(this.dataRow);
      } else if (e.keyCode == 39) {
        console.log('右键取消选中');
        this.checkOrCancelRowHandler(this.dataRow, 'right');
      } else if (e.keyCode == 13) {
        console.log('回车');
        this.$emit('keyEnter', this.selectionList);
        // removeEventListener("keyup", this.keyUp); //关闭键盘事件
      }
    },
    //改变表格选中某一行的颜色
    rowStyle(row) {
      if (row.rowIndex == this.currentIndex) {
        return {
          color: '#409eff',
        };
      }
    },
    dbClickHandler(row) {
      console.log(row, '双击一行');
    },
  },
  watch: {
    'config.pagination': {
      handler(newVal) {
        if (newVal.pageNumber <= 1) {
          this.isFirstPage = true;
        } else {
          this.isFirstPage = false;
        }
        if (newVal.pageSize * newVal.pageNumber >= this.config.pagination.total) {
          this.isLastPage = true;
        } else {
          this.isLastPage = false;
        }
      },
      immediate: true,
      deep: true,
    },
    // 监听默认值反填上去
    'config.defaultValue': {
      handler(newVal) {
        console.log(newVal, '默认值');
        if (Array.isArray(newVal) && newVal.length) {
          if (this.config.multiple) {
            // 多选的时候
            setTimeout(() => {
              this.multipleDefaultValue(newVal);
            }, 0);
          } else {
            // 单选的时候
            this.radioSelected = newVal[0];
          }
        }
      },
      immediate: true,
      deep: true,
    },
    // fix：修复数据加载后返回的
    tableList: {
      handler(newVal) {
        if (Array.isArray(newVal) && newVal.length) {
          if (this.config.multiple) {
            // 多选的时候
            setTimeout(() => {
              this.multipleDefaultValue(this.config.defaultValue);
            }, 0);
          } else {
            // 单选的时候
            this.radioSelected = this.config.defaultValue[0];
          }
        }
      },
      immediate: true,
      deep: true,
    },
    column: {
      handler(newVal) {
        this.checkedField = newVal.map((item) => item.field);
      },
      immediate: true,
      deep: true,
    },
  },
  components: {
    IElPager,
  },
};
</script>

<style lang="scss" scoped>
@import './index.scss';
</style>
